//
// Created by jiaxv on 2025/8/8.
//

#ifndef LDACS_CORENET_AS_ENTITY_H
#define LDACS_CORENET_AS_ENTITY_H
#include <ld_hashmap.h>

#include "elements.h"
#include "ldacs_corenet.h"
#include "ld_statemachine.h"

typedef struct as_defines_s {
    uint32_t UA;
    uint16_t SAC;
}as_defines_t;

typedef struct tag_defines_s {
    uint8_t width;
    const char *tag_name;
    uint8_t tag_len;
}tag_defines_t;


#define TAG_COUNT 9

#define SERIAL_TAG 0x001
#define UA_TAG 0x002
#define SAC_TAG 0x004
#define CURRENT_PEER_TAG 0x008
#define NEXT_PEER_TAG 0x010
#define AS_IP_TAG 0x020
#define GS_IP_TAG 0x040
#define GS_PORT_TAG 0x080
#define STATUS_TAG 0x100

enum TAGs {
    TAG_SERIAL = 0,
    TAG_UA,
    TAG_SAC,
    TAG_CURRENT_PEER,
    TAG_NEXT_PEER,
    TAG_AS_IP,
    TAG_GS_IP,
    TAG_GS_PORT,
    TAG_STATUS
};
#pragma pack(1)
typedef struct tag_json_s {
    uint32_t UA;
    uint16_t SAC;
    uint16_t CURR_GS_SAC;
    uint16_t NEXT_GS_SAC;
    buffer_t *AS_IP;
    buffer_t *GS_IP;
    uint16_t GS_port;
    buffer_t *status;
}tag_json_t;

static void free_tag_json(tag_json_t *tag) {
    if (tag) {
        if (tag->AS_IP) free_buffer(tag->AS_IP);
        if (tag->GS_IP) free_buffer(tag->GS_IP);
        if (tag->status) free_buffer(tag->status);
    }
    free(tag);
}
#pragma pack()

typedef struct as_entity_s {
    uint32_t UA;
    uint16_t SAC;
    uint16_t current_client_peer_sac;
    uint16_t next_peer_sac; // for AMM
    char IP_AS[GEN_ADDRLEN];
    char IP_GS[GEN_ADDRLEN];
    uint16_t port_GS;
    sm_statemachine_t amm_sm;
    sm_statemachine_t dbsm_sm;
    sm_statemachine_t gsg_sm;
}as_entity_t;

as_entity_t *init_as_entity(uint32_t UA, uint16_t SAC, uint16_t current_peer_sac, element_type_t ele_type, net_element_t *net_ele);

as_entity_t *init_as_entity_ip(uint16_t SAC, char *IP_AS, char *IP_GS, uint16_t port_GS);

l_err logoff_as_entity(as_entity_t *as);

l_err set_as_gs_ip(as_entity_t *as, char *new_IP, uint16_t new_port);

l_err set_as_as_ip(as_entity_t *as, char *new_IP);

struct hashmap *init_as_uenode_map();

struct hashmap *init_as_senode_map();

as_entity_t *set_as_enode(struct hashmap *map, as_entity_t *en);

as_entity_t *get_as_uenode_by_UA(struct hashmap *map, uint32_t UA);

as_entity_t *get_as_senode_by_SAC(struct hashmap *map, uint16_t SAC);

as_entity_t *get_as_senode_by_as_IP(struct hashmap *map, char *IP);

as_entity_t *get_as_uenode_by_SAC(struct hashmap *map, uint16_t SAC);

bool has_as_uenode(struct hashmap *map, const uint32_t UA);

bool has_as_senode(struct hashmap *map, const uint16_t SAC);

l_err delete_element_uenode_by_SAC(struct hashmap *map, uint16_t SAC);

l_err delete_element_senode_by_SAC(struct hashmap *map, uint16_t SAC);

as_entity_t *print_as_info(net_element_t *net_ele, struct hashmap *map, uint16_t mask);

l_err generate_as_info_json(net_element_t *net_ele, dashboard_set_cn_data_t *set);

#endif //LDACS_CORENET_AS_ENTITY_H